package org.bees.cms.web.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

import javax.persistence.Entity;

public class Beans {

	public static String getString(Object bean, String property) throws Exception {
		return bean == null ? "" : property == null ? bean.toString() : output(get(bean, property));
	}

	public static List<String> getList(Object bean, String property) throws Exception {
		return Arrays.asList(getString(bean, property).replace("[", "").replace("]", "").split(","));
	}

	public static Object get(Object bean, String name) throws Exception {
		if (bean == null || name == null || name.trim().equals("")) {
			return null;
		}
		if (name.contains(".")) {
			String _property = name.substring(0, name.indexOf("."));
			PropertyDescriptor descriptor = new PropertyDescriptor(_property, bean.getClass());
			Method reader = descriptor.getReadMethod();
			Object _bean = reader.invoke(bean);
			return get(_bean, name.substring(name.indexOf(".") + 1));
		} else {
			if (name.endsWith("()")) {
				Method method = bean.getClass().getMethod(name.replace("()", ""));
				return method.invoke(bean);
			} else {
				PropertyDescriptor descriptor = new PropertyDescriptor(name, bean.getClass());
				Method reader = descriptor.getReadMethod();
				return reader.invoke(bean);
			}
		}
	}

	public static void setProperty(Object bean, String property, Object value) throws Exception {
		if (property.contains(".")) {
			String _property = property.substring(0, property.indexOf("."));
			PropertyDescriptor descriptor = new PropertyDescriptor(_property, bean.getClass());
			Method reader = descriptor.getReadMethod();
			Object _bean = reader.invoke(bean);
			// 通常情况下 托管的对象的id是不能被修改的,不然提交事务时就失败!
			if (_bean == null || (property.trim().equals(_property + ".id") && reader.getReturnType().isAnnotationPresent(Entity.class))) {
				_bean = reader.getReturnType().newInstance();
				descriptor = new PropertyDescriptor(_property, bean.getClass());
				Method writer = descriptor.getWriteMethod();
				writer.invoke(bean, _bean);
			}
			setProperty(_bean, property.substring(property.indexOf(".") + 1), value);
		} else {
			PropertyDescriptor descriptor = new PropertyDescriptor(property, bean.getClass());
			Method writer = descriptor.getWriteMethod();
			writer.invoke(bean, value);
		}
	}

	private static String output(Object object) {
		return object == null ? "" : object.toString();
	}

	public static boolean contains(Class<?> clazz, String name) throws Exception {
		if (name.contains(".")) {
			String _name = name.substring(0, name.indexOf("."));
			if (_name.endsWith("()")) {
				Method method = null;
				try {
					method = clazz.getMethod(_name);
				} catch (Exception e) {
					return false;
				}
				Class<?> _clazz = method.getReturnType();
				return contains(_clazz, name.substring(name.indexOf(".") + 1));
			} else {
				PropertyDescriptor descriptor = null;
				try {
					descriptor = new PropertyDescriptor(_name, clazz);
				} catch (Exception e) {
					return false;
				}
				Method reader = descriptor.getReadMethod();
				Class<?> _clazz = reader.getReturnType();
				return contains(_clazz, name.substring(name.indexOf(".") + 1));
			}
		} else {
			if (name.endsWith("()")) {
				try {
					clazz.getMethod(name);
					return true;
				} catch (Exception e) {
					return false;
				}
			} else {
				try {
					new PropertyDescriptor(name, clazz);
					return true;
				} catch (Exception e) {
					return false;
				}
			}
		}
	}

	public static void main(String[] args) {

	}

}
